package com.jackykeke.opengldemo.renderer;

import android.opengl.GLES30;
import android.opengl.GLSurfaceView;

import com.jackykeke.opengldemo.R;
import com.jackykeke.opengldemo.utils.ResReadUtil;
import com.jackykeke.opengldemo.utils.ShaderUtil;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class SimpleRenderer implements GLSurfaceView.Renderer {


    private final FloatBuffer colorBuffer;
    private final FloatBuffer vertexBuffer;
    //    定义圆点坐标
    private float[] vertexPoint = new float[]{
            0.0f, 0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f
    };


    private float color[] = {
            0.0f, 1.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f
    };


    public SimpleRenderer() {
        //分配内存空间,每个浮点型占4字节空间
        vertexBuffer = ByteBuffer.allocateDirect(vertexPoint.length * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();

        //传入指定的坐标数据
        vertexBuffer.put(vertexPoint);
        vertexBuffer.position(0);


        colorBuffer = ByteBuffer.allocateDirect(color.length * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        //传入指定的数据
        colorBuffer.put(color);
        colorBuffer.position(0);
    }


//    编译着色器的流程也不复杂，主要流程就是
//
//1glCreateShader gl生成一个空的着色器程序，需要指定类型（顶点着色器，片段着色器）并返回着色器索引
//2glShaderSource gl载入着色器源码，需要输入1中生成的着色器索引，以及着色器源码
//3glCompileShader gl编译着色器，需要输入1中生成的着色器索引
//4glGetShaderiv gl检查编译结果（不会影响编译结果，一般用来辅助查错）
//重复上述1—4步骤，生成另外一个着色器
//现在已经有了两个着色器程序，需要做的就是连接两个着色器了
//7glCreateProgram 创建gl程序（也就是两个着色器链接成功之后的完整的gl程序），会返回程序索引
//8glAttachShader 给7创建的程序添加着色器程序，需要调用两次 分别添加顶点着色器和片段着色器
//9glLinkProgram 链接两个着色器
//10 glGetProgramiv gl检查链接结果，类似第4步
//
//作者：FENGAO
//链接：https://www.jianshu.com/p/1d08289d83b5
//来源：简书
//著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。

    private int mProgram;

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //设置背景颜色
        GLES30.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);

        //编译
        int vertexShaderId = ShaderUtil.compileVertexShader(ResReadUtil.readResource(R.raw.gray_filter_vertex_shader));
        int fragmentShaderId = ShaderUtil.compileFragmentShader(ResReadUtil.readResource(R.raw.gray_filter_fragment_shader));
        //链接程序片段
        mProgram = ShaderUtil.linkProgram(vertexShaderId, fragmentShaderId);
        //在OpenGLES环境中使用程序片段
        GLES30.glUseProgram(mProgram);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES30.glViewport(0, 0, width, height);
    }


    private static final int POSITION_COMPONENT_COUNT = 3;


    private int avPosition0 = 0;

    private int avPosition1 = 1;

    private int avPosition2 = 2;

    private int avPosition3 = 3;


    //常用图元类型
    //图元类型	描述
    //GL_POINTS	点精灵图元，对指定的每个顶点进行绘制。
    //GL_LINES	绘制一系列不相连的线段。
    //GL_LINE_STRIP	绘制一系列相连的线段。
    //GL_LINE_LOOP	绘制一系列相连的线段，首尾相连。
    //GL_TRIANGLES	绘制一系列单独的三角形。
    //GL_TRIANGLE_STRIP	绘制一系列相互连接的三角形。
    //GL_TRIANGLE_FAN	将传入的顶点作为扇面绘制 绘制一系列相互连接的三角形。

    @Override
    public void onDrawFrame(GL10 gl) {

        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);

        //准备坐标数据
        GLES30.glVertexAttribPointer(avPosition0, POSITION_COMPONENT_COUNT, GLES30.GL_FLOAT, false, 0, vertexBuffer);
        //启用顶点的句柄  //启用顶点属性 avPosition
        GLES30.glEnableVertexAttribArray(avPosition0);

        //绘制三角形颜色
        GLES30.glEnableVertexAttribArray(avPosition1);
        GLES30.glVertexAttribPointer(avPosition1, 4, GLES30.GL_FLOAT, false, 0, colorBuffer);
        //绘制图元
        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 3);

        //绘制圆点
        //准备坐标数据
        GLES30.glVertexAttribPointer(avPosition2, 3, GLES30.GL_FLOAT, false, 0, vertexBuffer);
        //启用顶点的句柄
        GLES30.glEnableVertexAttribArray(avPosition2);
        //绘制三个点
        GLES30.glDrawArrays(GLES30.GL_POINTS, 0, 3);


        //绘制正方体
//        GLES30.glVertexAttribPointer(avPosition3, 10, GLES30.GL_FLOAT, false, 0, vertexBuffer);
//        GLES30.glEnableVertexAttribArray(avPosition3);
//        GLES30.glDrawArrays(GLES30.GL_SAMPLER_CUBE, 0, 3);


//        绘制直线
        GLES30.glDrawArrays(GLES30.GL_LINE_STRIP, 0, 2);
        GLES30.glLineWidth(10);


        //绘制三角形
        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 2);

        //禁止顶点数组的句柄
        GLES30.glDisableVertexAttribArray(avPosition0);
        GLES30.glDisableVertexAttribArray(avPosition1);
        GLES30.glDisableVertexAttribArray(avPosition2);
//        GLES30.glDisableVertexAttribArray(avPosition3);

    }
}
